class Axises {

  constructor(option = {}, viewer, ) {

    this._viewer = viewer;


    /* 拖拽变量 */
    //是否处于拖拽状态
    this._isDragging = false;
    //是否在xy平面进行拖拽，否则沿z轴拖拽
    this._dragXY = false;
    //拖拽平面
    this._dragPlane = new Cesium.Plane(Cesium.Cartesian3.UNIT_X, 0); // 初始平面
    //鼠标指向位置相对于本原点的位移
    this._screenOffset = new Cesium.Cartesian3();
    //原点到球心坐标的变换矩阵
    this._trans = new Cesium.Matrix4();
    //逆矩阵
    this._invTrans = new Cesium.Matrix4();
    //顶点标识entity
    this._entity = undefined;


    this._id = "axises";
    this._prepareEdit = false;

    this._width = option.width || 0.1;
    this._headWidth = option.headWidth || 2 * this._width;
    this._length = option.length || 4;
    this._headLength = option.headLength || 2 * this._headWidth;

    //这里用的是圆锥几何对象，当topRadius和bottomRadius相同时，它就是一个圆柱
    const line = Cesium.CylinderGeometry.createGeometry(new Cesium.CylinderGeometry({
      length: this._length,
      topRadius: this._width,
      bottomRadius: this._width,
      slices: 4
    }));
    const flagLine = Cesium.CylinderGeometry.createGeometry(new Cesium.CylinderGeometry({
      length: 1000,
      topRadius: this._width,
      bottomRadius: this._width,
      slices: 4
    }));
    const arrow = Cesium.CylinderGeometry.createGeometry(new Cesium.CylinderGeometry({
      length: this._headLength,
      topRadius: 0,
      bottomRadius: this._headWidth,
      slices: 4
    }));
    let offset = (this._length + this._headLength) / 2
    Axises.translate(arrow, [0, 0, offset]);

    offset = this._length / 2 + 500;
    Axises.translate(flagLine, [0, 0, -offset]);

    const mx = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(90));
    const rotationX = Cesium.Matrix4.fromRotationTranslation(mx);
    const my = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(-90));
    const rotationY = Cesium.Matrix4.fromRotationTranslation(my);


    this._prim = new Cesium.Primitive({

      geometryInstances: [
        Axises.createOneGeometryInstance(this._id + "_zLIne", line, Cesium.Matrix4.IDENTITY, Cesium.Color.RED),
        Axises.createOneGeometryInstance(this._id + "_zArrow", arrow, Cesium.Matrix4.IDENTITY, Cesium.Color.RED),

        Axises.createOneGeometryInstance(this._id + "_xLIne", line, rotationX, Cesium.Color.GREEN),
        Axises.createOneGeometryInstance(this._id + "_xArrow", arrow, rotationX, Cesium.Color.GREEN),

        Axises.createOneGeometryInstance(this._id + "_yLIne", line, rotationY, Cesium.Color.BLUE),
        Axises.createOneGeometryInstance(this._id + "_yArrow", arrow, rotationY, Cesium.Color.BLUE),

        Axises.createOneGeometryInstance(this._id + "_zflagLine", flagLine, Cesium.Matrix4.IDENTITY, Cesium.Color.RED),

      ],
      asynchronous: false,

      appearance: new Cesium.PerInstanceColorAppearance()
    });

    viewer.scene.primitives.add(this._prim);

    viewer.scene.camera.moveEnd.addEventListener(
      () => {
        this.updateScale();
      }

    )
  }

  updateScale() {
    var dis = Cesium.Cartesian3.distance(this._viewer.camera.position, this.getPos());
    const rate = 64.0;
    var enlargeRate = dis / rate;
    Cesium.Matrix4.setScale(this._prim.modelMatrix, new Cesium.Cartesian3(enlargeRate, enlargeRate, enlargeRate), this._prim.modelMatrix);
  }

  isMe(id) {
    return id.startsWith(this._id);
  }
  /**
   * 按上面的方法画出的箭头在线的中间，我们需要把它平移到线的一端
   */
  static translate = function (geometry, offset) {
    const scratchOffset = new Cesium.Cartesian3();

    scratchOffset.x = offset[0];
    scratchOffset.y = offset[1];
    scratchOffset.z = offset[2];


    for (let i = 0; i < geometry.attributes.position.values.length; i += 3) {
      geometry.attributes.position.values[i] += scratchOffset.x;
      geometry.attributes.position.values[i + 1] += scratchOffset.y;
      geometry.attributes.position.values[i + 2] += scratchOffset.z;
    }
  }
  static createOneGeometryInstance = function (id, geometry, modelMatrix, color) {
    return new Cesium.GeometryInstance({
      id: id,
      geometry: geometry,
      modelMatrix: modelMatrix,
      attributes: {
        color: Cesium.ColorGeometryInstanceAttribute.fromColor(color)
      }
    });
  }


  setPos(pos) {
    this._prim.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(pos);
    this.updateScale();
  }
  getPos() {
    return Cesium.Matrix4.getTranslation(this._prim.modelMatrix, new Cesium.Matrix4());
  }

  /**
   * 准备拖拽操作，在点击航线顶点对应的entity时被调用
   * @param {*} entity 
   */
  prepareDragging(entity) {
    this._entity = entity;
    //this._entity.id.show=false;
    this.setPos(this._entity.id.position?._value);
    this._prim.show = true;
  }
  /**
   * 结束本次编辑任务
   */
  finishDragging() {
    this._entity.id.show = true;
    this._entity = undefined;
    this._prim.show = false;

  }

  /**
   * 拖拽初始化，在鼠标左键按下时被调用
   * @param {object} [movement] 鼠标屏幕位置
   * @param{String}[id] prim instance id
   */
  initDraging(movement, id) {

    this._dragXY = true;
    if (id.startsWith(this._id + "_z")) {
      this._dragXY = false;
    }

    this._viewer.scene.screenSpaceCameraController.enableRotate = false;
    this._viewer.scene.screenSpaceCameraController.enableZoom = false;

    this._isDragging = true;
    //以当前坐标原点（鼠标按下时本坐标系的原点）作为原点
    this._trans = Cesium.Matrix4.clone(this._prim.modelMatrix);
    this._invTrans = Cesium.Matrix4.inverse(this._trans, new Cesium.Matrix4());



    const ray = this._viewer.camera.getPickRay(movement.position);
    //将ray变换到本地坐标
    Cesium.Matrix4.multiplyByPoint(this._invTrans, ray.origin, ray.origin);
    var rot = Cesium.Matrix4.getMatrix3(this._invTrans, new Cesium.Matrix3());
    Cesium.Matrix3.multiplyByVector(rot, ray.direction, ray.direction);

    //定义本地坐标系下的dragplane
    if (this._dragXY) {
      this._dragPlane = new Cesium.Plane(Cesium.Cartesian3.UNIT_Z, 0);
    } else {
      var cros = Cesium.Cartesian3.cross(ray.direction, Cesium.Cartesian3.UNIT_Z, new Cesium.Cartesian3());
      Cesium.Cartesian3.cross(cros, Cesium.Cartesian3.UNIT_Z, cros);
      Cesium.Cartesian3.normalize(cros, cros);
      this._dragPlane = new Cesium.Plane(cros, 0);
    }


    const intersection = Cesium.IntersectionTests.rayPlane(ray, this._dragPlane);

    if (intersection) {
      this._screenOffset = Cesium.Cartesian3.subtract(new Cesium.Cartesian3(), intersection, new Cesium.Cartesian3());

    }


  }
  /**
   * 实施拖拽操作，在鼠标move事件里被调用
   * @param {Object} movement 鼠标屏幕位置
   * @returns 拖动成功，返回true，否则false
   */
  dragging(movement) {
    if (this._isDragging) {


      const ray = this._viewer.camera.getPickRay(movement.endPosition);

      Cesium.Matrix4.multiplyByPoint(this._invTrans, ray.origin, ray.origin);
      var rot = Cesium.Matrix4.getMatrix3(this._invTrans, new Cesium.Matrix3());
      Cesium.Matrix3.multiplyByVector(rot, ray.direction, ray.direction);

      const newPosition = Cesium.IntersectionTests.rayPlane(ray, this._dragPlane);

      if (newPosition) {
        var pos = Cesium.Cartesian3.add(newPosition, this._screenOffset, new Cesium.Cartesian3());
        if (!this._dragXY) {
          pos.x = pos.y = 0;
        }
        Cesium.Matrix4.multiplyByPoint(this._trans, pos, pos);

        this.setPos(pos);
      }
      return true;
    }
    return false;
  }
  stopDragging() {
    this._isDragging = false;
    this._viewer.scene.screenSpaceCameraController.enableRotate = true
    this._viewer.scene.screenSpaceCameraController.enableZoom = true
  }

  hiddenDragging(checked) {
    this._prim.show = checked
  }



}


export default Axises;
